//
//  YFPlayer.m
//  CamerDemo
//
//  Created by Winny Zhang on 2019/3/30.
//  Copyright © 2019 Winny Zhang. All rights reserved.
//

#import "YFPlayer.h"

@interface YFPlayer ()

/**
 播放器对象
 */
@property (nonatomic, strong) AVPlayer *player;

@end

@implementation YFPlayer

- (instancetype)initWithFrame:(CGRect)frame onView:(UIView *)view videoURL:(NSURL *)videoURL {
    self = [super initWithFrame:frame];
    if (self) {
        self.videoURL = videoURL;
        [self initPlayer:videoURL];
        [view addSubview:self];
    }
    return self;
}

- (void)initPlayer:(NSURL *)videoURL {
    // 创建播放器配置
    AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:videoURL];
    
    // 创建播放器
    AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:item];
    
    // 创建播放涂层
    AVPlayerLayer *palyerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
    palyerLayer.frame = self.bounds;
    palyerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
    [self.layer addSublayer:palyerLayer];
    self.player = player;
    self.playerLayer = palyerLayer;
    
    self.layer.backgroundColor = [UIColor blackColor].CGColor;
    
    // 添加 KVO、通知
    [self addKVOAndNotificaiton:item];
    [self.player play];
}
    
#pragma mark - KVO
/**
 *  通过KVO监控播放器状态
 *
 *  @param keyPath 监控属性
 *  @param object  监视器
 *  @param change  状态改变
 *  @param context 上下文
 */
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    AVPlayerItem *playerItem = object;
    if ([keyPath isEqualToString:@"status"]) {
        AVPlayerStatus status= [[change objectForKey:@"new"] intValue];
        if(status==AVPlayerStatusReadyToPlay){
            // NSLog(@"正在播放...，视频总长度:%.2f",CMTimeGetSeconds(playerItem.duration));
        }
    }else if([keyPath isEqualToString:@"loadedTimeRanges"]){
        NSArray *array=playerItem.loadedTimeRanges;
        CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次缓冲时间范围
        float startSeconds = CMTimeGetSeconds(timeRange.start);
        float durationSeconds = CMTimeGetSeconds(timeRange.duration);
        NSTimeInterval totalBuffer = startSeconds + durationSeconds;//缓冲总长度
        // NSLog(@"共缓冲：%.2f",totalBuffer);
    }
}

#pragma mark - Setter
- (void)setVideoURL:(NSURL *)videoURL {
    _videoURL = videoURL;
    [self removeObserver:self.player.currentItem];
    AVPlayerItem *newItem = [[AVPlayerItem alloc] initWithURL:videoURL];
    [self setupNextPlayer:newItem];
}

#pragma mark - 重新设置播放器，当有新的 videoURL 传进来的时候
- (void)setupNextPlayer:(AVPlayerItem *)item {
    [self.player seekToTime:CMTimeMakeWithSeconds(0, _player.currentItem.duration.timescale)];
    [self.player replaceCurrentItemWithPlayerItem:item];
    [self addKVOAndNotificaiton:item];
    if (self.player.rate == 0) {
        [self.player play];
    }
}

#pragma mark - 停止播放
- (void)stopPlaying {
    //如果在播放状态就停止
    if (self.player.rate == 1) {
        [self.player pause];
    }
}

#pragma mark - 添加 KVO 和通知
- (void)addKVOAndNotificaiton:(AVPlayerItem *)item {
    // 添加 KVO
    [item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    //监控网络加载情况属性
    [item addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
    // 添加通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:item];
}

#pragma mark - 通知执行方法
- (void)playbackFinished:(NSNotification *)info {
    // NSLog(@"视频播放完成");
    [self.player seekToTime:CMTimeMake(0, 1)];
    [self.player play];
}

#pragma mark - 移除通知 KVO
- (void)removeObserver:(AVPlayerItem *)item {
    [item removeObserver:self forKeyPath:@"status"];
    [item removeObserver:self forKeyPath:@"loadedTimeRanges"];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)dealloc {
    [self removeObserver: self.player.currentItem];
}

@end
